iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0

https://ithelp.ithome.com.tw/upload/images/20230923/20141551FXgddmkI1d.jpg

前言

前面學習了如何撰寫元件並添加樣式,具備了基礎撰寫元件的能力,接下來兩個章節都會打鐵趁熱來製作一個實際且極具代表性的元件 —— 「按鈕」。

定義問題

網站中要用到許多種類的按鈕,但每個按鈕都創立一個元件又難以管理,像是: <a> 按鈕、 <button> 按鈕……而按鈕的樣式更是千變萬化,像是:實心、外框、幽靈、底線連結、資訊、警告、危險、成功……如果每個按鈕都寫個元件也太累人了吧!於是希望能夠運用先前所學,撰寫一個「通用按鈕元件」,並且藉由傳入元件的 Props 來創建對應按鈕元件 —— 「 Button.astro」。

第一步:定義 Props

首先這個按鈕將會接收按鈕連結、樣式、大小等自訂的 Props,並且使用其餘參數將任何剩餘的 Props 給解構出來並放到標籤上:

---
const {href, theme, size, ...rest } = Astro.props
---

<a href={href} {...rest}>
  <slot/>
</a>

第二步:動態決定標籤

由於並不是任何按鈕都有連結,因此可以透過動態標籤來決定標籤的種類,如果存在 href 便是 <a> 標籤,反之則是 <button> 標籤:


---
const {href, theme, size, ...rest } = Astro.props
const Element = href ? 'a' : 'button'
---

<Element href={href} {...rest}>
  <slot/>
</Element>

第三步:添加按鈕樣式

預設將會套用 btn 樣式並且依照傳入的內容來決定按鈕風格與尺寸的樣式:

---
const {href, theme, size, ...rest } = Astro.props

const Element = href ? 'a' : 'button'
const themeClass = theme ? `btn--${theme}` : 'btn--primary'
const sizeClass = size ? `btn--${size}` : 'btn--md'
---

<Element href={href} class:list={['btn', themeClass, sizeClass]} {...rest}>
  <slot/>
</Element>

接著只需要撰寫對應的按鈕風格即可:

<style>
	/* 自行編寫樣式 */
	.btn {}
	.btn:hover {}
	.btn--primary {}
	.btn--secondary {}
	.btn--sm {}
	.btn--md {}
	.btn--lg {}
</style>

這樣 Button.astro 超級按鈕就完成了!輸入對應的 Props 與 Slot,該元件就會產生出對應種類的按鈕。

額外步驟:添加 Type

最後再為元件的 Props 添加 TypeScript。

interface Props {
  href?: string;
  size?: "sm" | "md" | "lg";
  theme?:
    | "primary"
    | "secondary"
}

至於標籤的型別實作我想與 Polymorphic type 有關,但我暫且看不懂這個 helper 的用法😅,如果你知道的話歡迎發言分享。

總結

在本章節綜合了先前「基礎元件」與「樣式」兩章節的內容,打造出一個通用的網頁按鈕元件,一起來實作看看吧。按鈕是網頁極具代表性的元件之一,下一章節講解整合 Tailwind 也會以這個例子出發,敬請期待!


上一篇
Day6 - 樣式
下一篇
Day8 - 實作整合 Tailwind
系列文
網頁開發沒有這麼簡單過!實際案例帶你上手 Astro.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言